/**
 *
 */
package com.naiterui.ehp.bs.doctor.service.impl;

import java.text.Collator;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.domain.City;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bs.doctor.dao.ICityDao;
import com.naiterui.ehp.bs.doctor.service.ICityService;
import com.naiterui.ehp.bs.doctor.utils.PropertyValueConstants;
import com.naiterui.ehp.bs.doctor.vo.CityVO;

@Service
public class AdCityServiceImpl implements ICityService {

    @Autowired
    private ICityDao cityDao;

    @Override
    public List<CityVO> getCityList(Integer pid) {
        List<City> cityList = cityDao.getCitysByParentId(pid);
        /*
         * 取出第一个城市判断 查询结果的行政级别
         */
        List<CityVO> cityVOList = new ArrayList<>();
        if (cityList == null || cityList.size() < 1) {
            return cityVOList;
        }
        City firstCity = cityList.get(0);
        if (firstCity.getType() == 2) {// 市
            List<City> shiCityList = new ArrayList<>();// 市级处理结果List
            City shenghui = null;
            Map<String, City> citysMap = new HashMap<>();
            for (Iterator iterator = cityList.iterator(); iterator.hasNext(); ) {
                City city = (City) iterator.next();
                if (city.getMunicipality() != null && city.getMunicipality() == 2) {// 省会
                    shenghui = city;
                    iterator.remove();
                } else {// 非省会
                    citysMap.put(city.getName(), city);
                }
            }
            if (shenghui != null) {
                shiCityList.add(shenghui);
            }
            /*
             * 按照城市首字母排序
             */
            Comparator comparator = Collator.getInstance(Locale.CHINA);
            String[] cityNameArray = citysMap.keySet().toArray(new String[citysMap.keySet().size()]);
            Arrays.sort(cityNameArray, comparator);
            for (String cityname : cityNameArray) {
                shiCityList.add(citysMap.get(cityname));
            }
            for (City city : shiCityList) {
                CityVO vo = new CityVO();
                BeanUtils.copyProperties(city, vo);
                cityVOList.add(vo);
            }
            return cityVOList;
        }
        for (City city : cityList) {
            CityVO vo = new CityVO();
            BeanUtils.copyProperties(city, vo);
            cityVOList.add(vo);
        }
        return cityVOList;
    }

    /**
     * 根据最终地区节点id返回完整的地址字符串
     * @param lastAreaId 城市表cms_city.id
     * @param spitWord 分隔符
     * @return 返回完整地区信息，如中国-广州-海珠
     */
    @Override
    public String getFullCityName(int lastAreaId, String spitWord) {
        StringBuilder sb = new StringBuilder();
        City city = cityDao.get(lastAreaId);
        if (city == null) {
            return "";
        }
        while (city != null) {
            sb.insert(0, city.getName());
            sb.insert(0, spitWord);
            int parentId = city.getParentId();
            if (parentId == 0 || city.getType() == 0) {
                break;
            }
            city = cityDao.get(parentId);
        }
        String areas = "";
        if (StringUtils.isNotBlank(spitWord)) {
            areas = sb.toString().substring(1);
        } else {
            areas = sb.toString();
        }
        return areas;
    }

    @Override
    public String getProAndCity(int lastAreaId, String spitWord) {
        StringBuilder sb = new StringBuilder();
        City city = cityDao.get(lastAreaId);
        if (city == null) {
            return "";
        }

        // 省级别，直接返回
        if (city.getType() == City.TYPE_PRO) {
            sb.insert(0, city.getName());
            sb.insert(0, spitWord);
            sb.insert(0, "中国");
            return sb.toString();
        }

        while (city != null) {
            // 拼接名称
            sb.insert(0, city.getName());
            sb.insert(0, spitWord);

            // 当前已到省级，退出
            if (city.getType() == City.TYPE_PRO) {
                break;
            }
            // 否则循环查找上级城市
            int parentId = city.getParentId();
            city = cityDao.get(parentId);
            // 父级为省，且为直辖市，直接返回 市 spitWord 区
            if (city.getType() == City.TYPE_PRO && city.getMunicipality() == 1) {
                break;
            }
        }

        // 如果有分隔符，去掉分隔符前缀
        String areas = "";
        if (StringUtils.isNotEmpty(spitWord)) {
            areas = sb.toString().substring(1);
        } else {
            areas = sb.toString();
        }
        return areas;
    }

    /**
     * 获取市这一级id 查询区域定价广东、陕西、河南历史遗留省会id
     * @Author fanjd
     * @Date 2017年9月18日
     * @since 1.0.0
     * @param cityId
     * @param flag 是否调用cityService.getCityId 0--不需要 1--需要
     * @return
     */
    @Override
    public Integer getSecondCityId(Integer cityId, Integer flag) {
        // 针对历史遗留数据 如果城市id为广东省 、河南省、山西省 传对应省会id
        if (cityId == null || cityId < 1) {
            return cityId;
        } else if (cityId == 6) {// 广东省id
            cityId = 76;// 广州id
        } else if (cityId == 11) {// 河南省id
            cityId = 149;// 郑州id
        } else if (cityId == 24) {// 陕西省id
            cityId = 331;// 西安id
        } else {
            // 如果flag==1 需要再调用getCityId()
            // 区域id必须传到市这一级 除了市 对方不认
            if (flag.equals(1)) {
                cityId = this.getCityId(cityId, PropertyValueConstants.RECURSION_COUNT);
            }
        }
        return cityId;
    }

    /**
     * 递归实现根据城市id找到对应的市级，限制递归次数
     * 增加递归次数限制，防止进入死循环
     * CityServiceImpl.getCityId()
     * @Author fanjd
     * @Date 2017年9月11日
     * @since 2.9.2
     * @param id
     * @param count 递归次数
     * @return
     */
    private Integer getCityId(Integer id, Integer count) {
        Integer cityId = PropertyValueConstants.WHOLE_COUNTRY_AREA;// 城市id默认为全国
        if (PropertyValueConstants.RUN_OUT_OF_TIME.equals(count)) {
            // 增加递归次数限制，防止城市级别挂错进入死循环 理论上城市级别不会超过5级
            // 若出现死循环，返回全国
            return cityId;
        }
        City city = cityDao.get(id);
        // 根据id查询城市信息 若为空城市id默认为全国
        if (null != city) {
            Integer type = city.getType();
            // id为市或者省直接返回
            if (City.TYPE_ALL.equals(type) || City.TYPE_PRO.equals(type) || City.TYPE_CITYS.equals(type)) {
                return id;
            } else {
                count--;
                return this.getCityId(city.getParentId(), count);
            }
        } else {
            return cityId;
        }
    }

    /**
     * 定位城市到市这一级
     * @Author fanjd
     * @Date 2017年9月18日
     * @since 1.0.0
     * @param ids
     * @return
     * @see ICityService#getSecondCityIdForMap(java.util.Set)
     */
    @Override
    public Map<Integer, Integer> getSecondCityIdForMap(Set<Integer> ids) {
        // key 原始id value 定位到市一级id map
        Map<Integer, Integer> secondMap = new HashMap<>();
        Set<Integer> thirdIds = new HashSet<>();
        List<City> citys = cityDao.getCitysByIds(ids);
        for (City city : citys) {
            if (City.TYPE_ALL.equals(city.getType()) || City.TYPE_PRO.equals(city.getType()) || City.TYPE_CITYS.equals(city.getType())) {
                secondMap.put(city.getId(), city.getId());
            } else {
                thirdIds.add(city.getId());
            }

        }
        // 第三级城市集合
        List<City> thirdCitys = cityDao.getCitysByIds(thirdIds);
        for (City city : thirdCitys) {
            secondMap.put(city.getId(), city.getParentId());
        }

        return secondMap;

    }

    @Override
    public List<CityVO> getCityAll() {
        List<CityVO> cityVOS = (List<CityVO>)RedisUtil.valueOps().getObject(CommonConstant.DOCTOR_CITY_LSIT_CACHE_KEY);
        if (cityVOS != null) {
            return cityVOS;
        }
        List<City> cityList = cityDao.getAll();
        cityVOS = BeanUtil.copyList(cityList, new ArrayList<>(), CityVO.class);
        listToTree(cityVOS);
        // 缓存城市信息
        RedisUtil.valueOps().setObject(CommonConstant.DOCTOR_CITY_LSIT_CACHE_KEY, cityVOS, 60 * 60 * 24);
        return cityVOS;
    }

    public static List<CityVO> listToTree(List<CityVO> list) {
        Set<Integer> parentIdSet = list.stream().map(CityVO::getParentId).collect(Collectors.toSet());
        Set<Integer> idSet = list.stream().map(CityVO::getId).collect(Collectors.toSet());
        parentIdSet.removeAll(idSet);
        // 用递归找子。
        return list.stream().filter(tree -> parentIdSet.contains(tree.getParentId()))
            .map(tree -> findChildren(tree, list)).collect(Collectors.toList());
    }

    private static CityVO findChildren(CityVO tree, List<CityVO> list) {
        list.stream().filter(node -> node.getParentId().equals(tree.getId())).map(node -> findChildren(node, list))
            .forEachOrdered(children -> tree.getChildren().add(children));
        return tree;
    }
}
